MapStruct使用指南(二) 您所在的位置:网站首页 long 转为integer MapStruct使用指南(二)

MapStruct使用指南(二)

2024-07-15 22:53| 来源: 网络整理| 查看: 265

MapStruct数据类型转换 基本类型的转换

​ mapstruct会自动完成基本类型的一些隐式转换(包括:boolean、byte、char、int、long、float、double、String及其包装类等)

相同基本类型可以直接转换

@Mapping(target = "intValue", source = "intValue")

基本类型都可以转String类型,如int/Integer转String

实际上使用的是string.valueOf()方法,支持所有基本类型转String。

@Mapping(target = "stringValue", source = "intValue") @Mapping(target = "stringValue", source = "booleanValue")

所有的数字类型及其包装类都可以直接转换,如int/Integer、long/Long之间转换。

实际上会进行强制转换,长字节类型转短字节类型会发生截断,注意数据溢出,精度丢失等问题。

@Mapping(target = "byteValue", source = "intValue") // 生成代码示例,257强制转byte后溢出,实际为1 target.setByteValue((byte) intValue);

基本类型与其包装类型可以直接转换,且会自动生成判空代码

@Mapping(target = "intValue", source = "integerValue") // 生成代码示例,自动生成判空代码 if (source.getIntegerValue() != null) { target.setIntValue( source.getIntegerValue() ); }

StringBuilder与String可以直接转换

大数类型与基本类型及其包装类、String可以直接转换

时间类型转换

隐式转换规则

java.time.Instant与java.util.Date直接转换java.sql.Date与java.util.Date直接转换java.sql.Time 与java.util.Date直接转换java.sql.Timestamp 与java.util.Date直接转换

java.util.Date转String,使用系统默认时区

@Mapper public interface TimeMapper { TimeMapper INSTANCE = Mappers.getMapper(TimeMapper.class); @Mapping(target = "date", source = "date", dateFormat = "yyyy-MM-dd HH:MM:ss") TimeVo toTimeVo(TimeEntity timeEntity); } public class TimeEntity { private Date date; } public class TimeVo { private String date; }

java.util.Date可以与String转换,使用系统默认时区

@Mapper public interface TimeMapper { TimeMapper INSTANCE = Mappers.getMapper(TimeMapper.class); @Mapping(target = "date", source = "instant", dateFormat = "yyyy-MM-dd HH:MM:ss") TimeVo toTimeVo(TimeEntity timeEntity); } public class TimeEntity { private Instant instant; } public class TimeVo { private String date; } 集合类型的转换

相同类型的集合可以直接转换

@Mapping(target = "list", source = "list")

基本类型(及其包装类)的相同集合可以直接转换

如List转List

@Mapping(target = "integerList", source = "stringList")

生成代码示例,自动生成一个stringListToIntegerList方法。

target.setList( stringListToIntegerList( source.getList() ) ); protected List stringListToIntegerList(List list) { if ( list == null ) { return null; } List list1 = new ArrayList( list.size() ); for ( String string : list ) { list1.add( Integer.parseInt( string ) ); } return list1; }

同类型的List和Set可以直接转换

@Mapping(target = "set", source = "list") 复杂集合的转换

复杂List、Set的转换

如需实现List转List,可以先表示A转B的方法toB(),再表示List转List的方法toBList(),不需要显式调用toB()方法,mapstruct会在toBList()方法中自动循环调用toB()方法。

@Getter @Setter @ToString public class A { private String aValue; } @Getter @Setter @ToString public class B { private String bValue; } @Mapper public interface Converter { Converter INSTANCE = Mappers.getMapper(Converter.class); @Mapping(target = "bValue", source = "aValue") B toB(A a); // 不需要写任何注解,会自动调用toB(A a)方法 List toBList(List aList); }

生成代码示例:

public List toBList(List aList) { if ( aList == null ) { return null; } List list = new ArrayList( aList.size() ); for ( A a : aList ) { list.add( toBaseEntity( a ) ); } return list; }

复杂Map的转换

如需要实现Map转换为Map,类似与List的转换,需要先分别实现A转换为B的toB()、C转为D的toD()方法,然后再实现Map转换为Map的toMap()方法

@Getter @Setter @ToString public class A { private String aValue; } @Getter @Setter @ToString public class B { private String bValue; } @Getter @Setter @ToString public class C { private String cValue; } @Getter @Setter @ToString public class D { private String dValue; } @Mapper public interface Converter { Converter INSTANCE = Mappers.getMapper(Converter.class); @Mapping(target = "bValue", source = "aValue") B toB(A a); @Mapping(target = "dValue", source = "cValue") D toD(C c); // 不需要写任何注解,会自动调用toB(A a)方法和D toD(C c)方法 Map toMap(Map map); }

生成代码示例:

public Map toMap(Map map) { if ( map == null ) { return null; } Map map = new HashMap( Math.max( (int) ( baseVoMap.size() / .75f ) + 1, 16 ) ); for ( java.util.Map.Entry entry : map.entrySet() ) { B key = toB( entry.getKey() ); D value = toD( entry.getValue() ); map.put( key, value ); } return map; } 枚举值的转换 两个Enum之间的转换

两个枚举值之间可以使用@ValueMapping进行转换,举例:对DML语句的进行分类,定义两个枚举,两个对象分别拥有这两个枚举属性

public enum DMLEnum { SELECT("SELECT * FROM test"), INSERT("INSERT INTO test VALUES(...)"), INSERT_OR_UPDATE("INSERT INTO test VALUES(...) ON DUPLICATE KEY UPDATE..."), UPDATE("UPDATE test SET ... WHERE ..."), DELETE("DELETE FROM test WHERE ..."); private final String sql; DMLEnum(String sql) { this.sql = sql; } } public enum OperationEnum { CREATE, UPDATE, READ, DELETE } public class BaseVo { private OperationEnum operationEnum; } public class BaseEntity { private DMLEnum dmlEnum; }

映射如下:

Entity VO SELECT INSERT INSERT_OR_UPDATE UPDATE DELETE CREATE UPDATE READ DELETE

Mapper:

@Mapper public interface DMLMapper { DMLMapper INSTANCE = Mappers.getMapper(DMLMapper.class); @ValueMapping(target = "CREATE", source = "INSERT") @ValueMapping(target = "CREATE", source = "INSERT_OR_UPDATE") @ValueMapping(target = "READ", source = "SELECT") @ValueMapping(target = "UPDATE", source = "UPDATE") @ValueMapping(target = "DELETE", source = "DELETE") OperationEnum toOperationEnum(DMLEnum dmlEnum); @Mapping(target = "operationEnum", source = "dmlEnum") BaseVo toBaseVo(BaseEntity baseEntity); }

测试:

public class DMLMapperTest { @Test public void test_toOperationEnum() { System.out.println(DMLMapper.INSTANCE.toOperationEnum(DMLEnum.INSERT_OR_UPDATE)); System.out.println(DMLMapper.INSTANCE.toOperationEnum(DMLEnum.INSERT)); } @Test public void test_toBaseVo() { BaseEntity baseEntity = new BaseEntity(); baseEntity.setDmlEnum(DMLEnum.UPDATE); BaseV baseVo = DMLMapper.INSTANCE.toBaseVo(baseEntity); System.out.println(baseVo.getOperationEnum()); } } /***************************************output****************************** * CREATE * CREATE **************************************************************************** * UPDATE **************************************************************************** 枚举与字符串之间的转换

枚举的字面值(name()方法返回值)和字符串可以互相转换

枚举值->字符串

直接将枚举值映射为字符串值,以上面枚举DMLEnum为例,映射为字符串String

@Mapper public interface DMLMapper { DMLMapper INSTANCE = Mappers.getMapper(DMLMapper.class); @Mapping(target = "dml", source = "dmlEnum") BaseVo toBaseVo(BaseEntity baseEntity); } public class BaseVo { private String dml; } public class BaseEntity { private DMLEnum dmlEnum; }

测试

public class DMLMapperTest { @Test public void test_toBaseVo() { BaseEntity baseEntity = new BaseEntity(); baseEntity.setDmlEnum(DMLEnum.UPDATE); BaseVo baseVo = DMLMapper.INSTANCE.toBaseVo(baseEntity); System.out.println(baseVo.getDml()); } } /***************************************output****************************** * UPDATE ****************************************************************************

字符串->枚举

@Mapper public interface DMLMapper { DMLMapper INSTANCE = Mappers.getMapper(DMLMapper.class); @Mapping(target = "dmlEnum", source = "dml") BaseEntity toBaseEntity(BaseVo baseVo); } public class BaseVo { private String dml; } public class BaseEntity { private DMLEnum dmlEnum; }

测试

public class DMLMapperTest { @Test public void test_toBaseEntity() { BaseVo baseVo = new BaseVo(); baseVo.setDml("UPDATE"); BaseEntity baseEntity = DMLMapper.INSTANCE.toBaseEntity(baseVo); System.out.println(baseEntity.getDmlEnum()); } } /***************************************output****************************** * UPDATE **************************************************************************** 字符串转枚举再转字符串

字符->找到对应枚举->得到枚举的字符串属性

dml: String -> dmlEnum: DMLEnum->sql: String

@Mapper public interface DMLMapper { DMLMapper INSTANCE = Mappers.getMapper(DMLMapper.class); @Mapping(target = "sql", expression = "java(org.numb.mapstruct.entity.DMLEnum.fromName(baseVo.getDml()).getSql())") BaseEntity toBaseEntity(BaseVo baseVo); } public class BaseVo { private String dml; } public class BaseEntity { private String sql; }

测试

public class DMLMapperTest { @Test public void test_toBaseEntity() { BaseVo baseVo = new BaseVo(); baseVo.setDml("UPDATE"); BaseEntity baseEntity = DMLMapper.INSTANCE.toBaseEntity(baseVo); System.out.println(baseEntity.getSql()); } } /***************************************output****************************** * UPDATE test SET ... WHERE ... **************************************************************************** 引用对象映射

mapstruct会自动识别并引用当前Mapper中的映射方法,如A对象包含B对象,C对象包含D对象。A对象映射为C对象,同时希望把B对象映射为D对象

C A D B

可以在Mapper中同时定义A->C、B->D的映射对象,当A->C转换时,会自动调用C->D的映射。

如下,Car中包含Person对象,调用carToCarDto时会自动调用personToPersonDto

@Mapper public interface CarMapper { CarDto carToCarDto(Car car); PersonDto personToPersonDto(Person person); }

引用对象映射遵循一些规则:

如果source和target类型相同(包括集合类),会调用set、constructor方法直接赋值。

如果source和target类型不同,会在当前Mapper中寻找有相同类型入参和相同返回值类型的映射方法,如果存在则自动引用该方法。

如果不存在上述映射方法,寻找是否有内置转换代码(built-in conversion)可以完成转换

如果上述方法都不存在,mapstruct尝试自动生成转换方法

如果不能完成转换,则报错。

自定义映射方法

如果Mapstruct有些场景不能完成,可以自定义转化方法

public interface CarMapper{ @Mapping(target = "personDto", source = "person") CarDto toCarDto(Car car); // 自定义方法实现 static PersonDto toPersonDto(Person person) { PersonDto personDto = new PersonDto(); // do something return personDto; } }

也可以使用@Mapping的表达式属性expression显式指定某一个参数。注意expression不会自动导入,所以表达式中要使用其他类的方法,要带全类名(包名.类名.函数名)或者使用@Mapper的imports显式导入所需要的类。

@Mapper(imports = {com.xxx.xxx.class}) public interface CarMapper{ @Mapping(target = "personDto", expression = "toPersonDto(person)") CarDto toCarDto(Car car); // 自定义方法实现 static PersonDto toPersonDto(Person person) { PersonDto personDto = new PersonDto(); // do something return personDto; } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有